﻿// 版权所有 (C) Microsoft Corporation。保留所有权利。

// ImperativeSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;

class NativeMethods
{
    // 这是对非托管代码的调用。执行此方法需要
    // UnmanagedCode 安全权限。如果没有此权限，
    // 则调用此方法的尝试将引发 SecurityException：
    [DllImport("msvcrt.dll")]
    public static extern int puts(string str);
    [DllImport("msvcrt.dll")]
    internal static extern int _flushall();
}

class MainClass
{
    private static void CallUnmanagedCodeWithoutPermission()
    {
        // 创建安全权限对象以描述
        // UnmanagedCode 权限：
        SecurityPermission perm = 
           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);

        // 拒绝当前权限集中的 UnmanagedCode。
        // 在此方法返回之前，在此线程上调用的任何方法
        // 都不允许访问非托管代码。
        // 即使 CallUnmanagedCodeWithPermission 方法
        // 是从已经为非托管代码调用了
        // Assert 的堆栈帧调用的，也无法调用本机
        // 代码。由于此处使用了 Deny，因此权限 
        // 被覆盖。
        perm.Deny();

        try
        {
            Console.WriteLine("Attempting to call unmanaged code without permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code without permission. Whoops!");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");
        }
    }

    private static void CallUnmanagedCodeWithPermission()
    {
        // 创建安全权限对象来描述
        // UnmanagedCode 权限：
        SecurityPermission perm = 
           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);

        // 检查您是否具有访问非托管代码的权限。
        // 如果您没有访问非托管代码的权限，则
        // 此调用将引发 SecurityException。
        // 即使 CallUnmanagedCodeWithPermission 方法
        // 是从已经为非托管代码调用了 Assert 的堆栈帧调用的，
        // 也不能调用本机
        // 代码。由于此处使用了 Deny，因此权限被 
        // 覆盖。
        perm.Assert();

        try
        {
            Console.WriteLine("Attempting to call unmanaged code with permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code with permission.");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code. Whoops!");
        }
    }

    public static void Main() 
    {
        // 该方法本身将为非托管代码调用安全权限 Deny，
        // 这会重写此堆栈帧中的 Assert
        // 权限。
        SecurityPermission perm = new 
            SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
        perm.Assert();
        CallUnmanagedCodeWithoutPermission();

        // 该方法本身将为非托管代码调用安全权限 Assert，
        // 这会重写此堆栈帧中的 Deny
        // 权限。
        perm.Deny();
        CallUnmanagedCodeWithPermission();
    }
}

